/**
 *  学习目标：Todos 案例 ts - redux
    重点：
      1. 💥使用官方封装的useAppSelector
      2. 💥Reducer中的action不要解构
      3. 💥reducer函数加上返回值
 *  需求
 *    1. 创建redux仓库
 *    2. state类型丢失问题的修复
      3. 💥使用官方封装的useAppSelector
      4. ✅Main列表渲染
      5. ✅根据id删除一条数据
      6. ✅更新一条数据的选中状态
      7. ✅清除已完成
      8. ✅统计剩余
      9. ✅点谁谁高亮-排它判断
      10. ✅点谁谁高亮-修改type
      11. 切换数据 
      💥 计算属性不要放在Redux的state中，减轻state的设计
      12. 新增任务 - 监听回车、Esc、非空判断
      13. 新增任务 - 到list中
      14. 数据缓存
      15. ✅小选影响全选 
        15.1 通过计算属性计算小选矿的选中状态得到isAll
        15.2 将isAll绑定在全选按钮上
      16. ✅全选影响小选
        16.1 通过onChange事件获取checked
        16.2 定义TodoAction联合类型
        16.3 reducer中增加switch分支逻辑
        16.4 定义全选的action函数
        16.5 dispatch触发action
 */
import React, { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useAppSelector } from './store';
import {
  addTodo,
  checkedAllTodo,
  clearIsDoneTodo,
  delTodoById,
  updateTodoById,
  updateType,
} from './store/action/todo';
import './styles/base.css';
import './styles/index.css';

export default function App() {
  const { list, type } = useAppSelector((state) => state.todo);
  // 14.1 在App中监听list，type的变化
  useEffect(() => {
    // 14.2 每次变化，将最新的值存到缓存中
    localStorage.setItem('todo-list', JSON.stringify(list));
    localStorage.setItem('todo-type', type);
  }, [list, type]);

  return (
    <section className="todoapp">
      {/* 头部 */}
      <Header></Header>
      {/* 主体 */}
      <Main></Main>
      {/* 底部 */}
      <Footer></Footer>
    </section>
  );
}
function Footer() {
  const dispatch = useDispatch();
  // 8.1 取出list
  const { list, type } = useAppSelector((state) => state.todo);
  // 8.2 计算属性得到未完成任务组成的数组
  const restLen = list.filter((item) => !item.isDone).length;
  return (
    <footer className="footer">
      <span className="todo-count">
        {/* 8.3 显示内容 */}
        <strong>{restLen}</strong> 剩余
      </span>
      <ul className="filters">
        <li>
          {/* 9.4 排它判断 */}
          <a
            onClick={() => dispatch(updateType('all'))}
            className={type === 'all' ? 'selected' : ''}
            href="#/"
          >
            全部
          </a>
        </li>
        <li>
          <a
            onClick={() => dispatch(updateType('active'))}
            className={type === 'active' ? 'selected' : ''}
            href="#/active"
          >
            未完成
          </a>
        </li>
        <li>
          <a
            onClick={() => dispatch(updateType('completed'))}
            className={type === 'completed' ? 'selected' : ''}
            href="#/completed"
          >
            已完成
          </a>
        </li>
      </ul>
      {/* 7.5 触发dispatch */}
      <button className="clear-completed" onClick={() => dispatch(clearIsDoneTodo())}>
        清除已完成
      </button>
    </footer>
  );
}

function Main() {
  // 1.6验证获取state
  // 2.2. 导入到App中，手动绑定给useSelector

  // 3.2 useAppSelector 替换掉useSelector
  // 4.2 渲染Main组件
  const { list, type } = useAppSelector((state) => state.todo);
  const dispatch = useDispatch();
  const showList = list.filter((item) => {
    // 如果type为all, 返回值为true
    if (type === 'all') return true;
    // 如果type为active, 返回值!item.isDone为true
    if (type === 'active') return !item.isDone;
    // 如果type为completed, 返回值item.isDone为true
    return item.isDone;
  });

  // 15.1 通过计算属性计算小选矿的选中状态得到isAll
  const isAll = list.length ? list.every((item) => item.isDone) : false;
  // 15.2 将isAll绑定在全选按钮上

  //

  return (
    <section className="main">
      {/* 16.1 通过onChange事件获取checked */}
      <input
        id="toggle-all"
        className="toggle-all"
        type="checkbox"
        checked={isAll}
        onChange={(e) => dispatch(checkedAllTodo(e.target.checked))}
      />
      <label htmlFor="toggle-all">全选</label>
      <ul className="todo-list">
        {/* 4.3 遍历渲染 */}
        {showList.map((item) => {
          return (
            <li className={item.isDone ? 'completed' : ''} key={item.id}>
              <div className="view">
                <input
                  className="toggle"
                  type="checkbox"
                  checked={item.isDone}
                  //  6.4 点击checkbox触发dispatch更新Action
                  onChange={() => dispatch(updateTodoById(item.id))}
                />
                <label>{item.task}</label>
                {/* 5.4 调用aciton */}
                <button className="destroy" onClick={() => dispatch(delTodoById(item.id))}></button>
              </div>
            </li>
          );
        })}
      </ul>
    </section>
  );
}

function Header() {
  const [task, setTask] = useState('');
  const dispatch = useDispatch();
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    // 12.3 非空判断
    if (!task.trim() && e.key === 'Enter') {
      return alert('不能为空');
    }

    // 12.4 监听回车事件
    if (e.key === 'Enter') {
      console.log('回车触发了  ----->  ');
      // 13.4 dispatch触发Action
      dispatch(addTodo(task));
      setTask('');
    }

    // 12.5 监听Esc按键
    if (e.key === 'Escape') {
      setTask('');
    }
  };
  return (
    <header className="header">
      <h1>todos</h1>
      <input
        // 12.1 改造Header为受控组件， 使用useState
        onChange={(e) => setTask(e.target.value)}
        // 12.2 监听回车事件
        onKeyDown={handleKeyDown}
        className="new-todo"
        placeholder="需要做什么"
        autoFocus
        value={task}
      />
    </header>
  );
}
